package com.wangge.test1.function;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import java.util.stream.Stream;


import org.junit.Before;
import org.junit.Test;

/**
 * jdk1.8 Stream测试 Stream 的sort和filter进行中间操作而forEach则进行终端操作
 * Stream的各种操作只修改Stream本身,其元数据不修改; Api:filter(过滤),sort(排序),map(转化),forEach(遍历)
 * match(匹配判断)
 * 
 * jdk1.8 Map的新方法;getOrDefault,forEach,merger(key,newVal,BiFunction(oldVal,newVal),computerIfPresent,
 * computerIfAbsent,remove(key,value)
 * @author yangqc
 *
 */
public class StreamTest {
	List<String> rlist = new ArrayList<String>();
	Stream<String> rStream = null;

	@Before
	public void testInit() {
		String[] ar = new String[] { "A", "B", "C", "D" };
		for (int i = 0; i < ar.length; i++) {
			rlist.add(ar[i] + ar[i] + ar[i] + i);
			rlist.add(i + ar[i] + ar[i] + ar[i]);
		}
		rStream = rlist.stream();
	}

	/**
	 * stream过滤操作
	 */
	@Test
	public void testFilter() {
		rlist.stream().filter((s) -> s.startsWith("A")).forEach(System.out::println);
		rlist.stream().filter((s) -> s.contains("A")).forEach(System.out::println);
	}

	/**
	 * sort排序操作
	 */
	@Test
	public void testSort() {

		rlist.stream().sorted().forEach(System.out::println);
		System.out.println("乱排序开始");
		rlist.stream().sorted((a, b) -> a.charAt(1) - (b.charAt(0))).forEach(System.out::println);
	}

	/**
	 * map 元素转化,接受的是Function实例
	 */
	@Test
	public void testmap() {
		rlist.stream().map(String::toLowerCase).forEach(System.out::println);
		;
	}

	/**
	 * Match匹配后跟Predicate allMatch 全部匹配 anyMatch 任一匹配 nonmatch 都不匹配
	 */
	@Test
	public void testMatch() {
		Boolean allmatch = rlist.stream().allMatch((s) -> s.startsWith("A"));
		System.out.println(allmatch);
		Boolean anymatch = rlist.stream().anyMatch((s) -> s.startsWith("A"));
		System.out.println(anymatch);
		Boolean nonmatch = rlist.stream().noneMatch((s) -> s.startsWith("A"));
		System.out.println(nonmatch);

	}

	/**
	 * 计数count 末端运算,返回Long 减缩运算 reduce 末端运算,返回Optional
	 */
	@Test
	public void testCount() {
		Long acount = rlist.stream().filter((s) -> s.startsWith("A")).count();
		System.out.println(acount);
		Predicate<String> startPred = (s) -> s.startsWith("A");
		Long orCount = rlist.stream().filter(startPred.or((s) -> s.endsWith("1"))).count();
		System.out.println(orCount);

		Optional<String> rout = rStream.reduce((a, b) -> a + "##" + b);
		rout.ifPresent(System.out::println);
	}

	/**
	 * 排序效率测试,System.nanoTime()
	 * TimeUnit.NANOSECONDS.toMillis(Long duration)
	 */
	@Test
	public void testParall() {
		int max = 1000 * 1000;
		List<String> list = new ArrayList<>();
		for (int i = 0; i < max; i++) {
			list.add(UUID.randomUUID().toString());
		}
		Long t1 = System.nanoTime();
		Long count1 = list.stream().sorted().count();
		System.out.println(count1);
		long consumer = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - t1);
		System.out.println(String.format("sequential sort took %d ms", consumer));
		
		long t2=System.nanoTime();
		long count2=list.parallelStream().sorted().count();
		System.out.println(count2);
		Long took2=TimeUnit.NANOSECONDS.toMillis(System.nanoTime()-t2);
		System.out.println(String.format("parallel sort took %d ms", took2));
	}

	/**
	 * Map类新的API
	 * 遍历:forEach(BiConsumer);BiConsumer双入参消费者
	 * 非空则进行操作:computeIfPresent(key,BiFunction);BiFunction算入参函数
	 * 为空则进行操作 :computerIfAbsent(key,Function); Function 函数
	 * 只删除特定值: remove(key,value) ;根据key和value配对来删除Map.Entry可用于过滤;
	 * 值为空则取默认: getOrDefault(key,defaultValue);
	 * 合并map某条记录:merge(K key, V value,
            BiFunction<? super V, ? super V, ? extends V> remappingFunction);如果原值为null,则put该val;
                不为null,则用BiFunction<oldval,val>函数值进行put操作;
	 */
	@Test
	public void testMap(){
		Map<Integer,String> map=new HashMap<>();
		for(int i=0;i<10;i++){
			map.put(i, "val"+i);
		}
		map.forEach((key,value)->System.out.println(value));
		System.out.println("---------test computerIfPresent------------");
		map.computeIfPresent(3, (key,val)->key+val);
		System.out.println(map.get(3));
		System.out.println("---------test computerIfPresent------------");
		map.computeIfAbsent(12, (key)->key+"add");
		System.out.println(map.get(12));
		System.out.println("---------test remove------------");
		System.out.println(map.remove(3,"val3"));
		System.out.println(map.get(3));
		System.out.println("---------test getOrDefault------------"+map.getOrDefault(45,"45321"));
		map.merge(4, "aaa",(oldValue, value)->value.concat(oldValue));
		System.out.println(map.get(4));
	}
	
}
